package network;

import gui.panel.HomePanel;
import gui.panel.MainTabs;

import java.io.IOException;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import Signals.Hello;

import network.io.UDPReceiver;
import network.io.UDPSender;

public class NetworkInterface {

	private UDPSender sendManager;
	private UDPReceiver receiveManager;
	private DatagramSocket socket;
	private String nickname;
	private int port;
	private List<String> connectedUsers;
	private Thread receivingThread;
	private MainTabs mainTabs;
	
	/**
	 * Creates a new Network Interface
	 * @param nickname
	 * @param port
	 * @throws IOException
	 */
	public NetworkInterface(String nickname, int port) throws IOException {
		this.setPort(port);
		this.setSocket(port);
		this.setReceiveManager(new UDPReceiver(this));	
		this.setSendManager(new UDPSender(this));
		this.setNickname(nickname);
		this.setConnectedUsers(new ArrayList<String>());
		// create a new receiving thread and launch it
		this.receivingThread = new Thread(this.getReceiveManager());
	}
	
	/**
	 * Runs the receiving thread
	 */
	public void startReceiving() {
		this.receivingThread.start();
		this.getSendManager().sendBroadcast(new Hello(this.getNickname()));
	}
	
	/**
	 * Interrupts the receiving thread
	 */
	public void stopReceiving() {
		this.receiveManager.setConnected(false);
		this.receivingThread.interrupt();
	}
	/**
	 * Closes the socket
	 */
	public void closeSocket() {
		this.socket.close();
		this.receiveManager.setConnected(false);
	}

	public Boolean isConnected(String nickname) {
		Boolean b = false;
		for(String s : connectedUsers) {
			if (s == nickname) {
				b = true;
				break;
			}
		}
		return b;
	}
	
	public void addUser(String nickname) {
		if (!isConnected(nickname))
			this.connectedUsers.add(nickname);
	}
	
	public void removeUser(String nickname) {
		if (isConnected(nickname))
			this.connectedUsers.remove(nickname);
	}

	public String parseUserName (String nickname) {
		Pattern p = Pattern.compile("(.+)@(.+)");
		Matcher m = p.matcher(nickname);
		boolean b = m.matches();
		String result = "";
		if (b) {result = m.group(1);}
		return result;
	}

	public String parseIP (String nickname) {
		Pattern p = Pattern.compile("(.+)@(.+)");
		Matcher m = p.matcher(nickname);
		boolean b = m.matches();
		String result = "";
		if (b) {result = m.group(2);}
		return result;
	}
	
	public DatagramSocket getSocket() {
		return socket;
	}

	public void setSocket(int port) {
		try {
			this.socket = new DatagramSocket(port);
			this.socket.setSoTimeout(100);
		} catch (SocketException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public UDPReceiver getReceiveManager() {
		return receiveManager;
	}

	public void setReceiveManager(UDPReceiver receiveManager) {
		this.receiveManager = receiveManager;
	}

	public UDPSender getSendManager() {
		return sendManager;
	}

	public void setSendManager(UDPSender sendManager) {
		this.sendManager = sendManager;
	}

	public String getNickname() {
		return nickname;
	}

	public void setNickname(String nickname) {
		this.nickname = nickname;
	}

	public List<String> getConnectedUsers() {
		return connectedUsers;
	}

	public void setConnectedUsers(List<String> connectedUsers) {
		this.connectedUsers = connectedUsers;
	}

	public int getPort() {
		return port;
	}

	public void setPort(int port) {
		this.port = port;
	}

	public Thread getReceivingThread() {
		return receivingThread;
	}

	public void setReceivingThread(Thread receivingThread) {
		this.receivingThread = receivingThread;
	}

	public MainTabs getMainTabs() {
		return mainTabs;
	}

	public void setMainTabs(MainTabs mainTabs) {
		this.mainTabs = mainTabs;
	}
	
}
